/***********************************************************************
 * Module:  HibernateDaoImpl.java
 * Author:  Administrator
 * Purpose: Defines implementation class of HibernateDao interface
 ***********************************************************************/

package edu.zzuli.model.dao.hibernate;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.criterion.Criterion;
import org.springframework.context.ApplicationContext;
import org.springframework.dao.DataAccessException;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import edu.zzuli.model.dao.BasePO;

/**
 * Class that implements <Code>HibernateDao</Code> interface.
 * 
 */
public class HibernateDaoImpl extends HibernateDaoSupport implements HibernateDao {

	protected static final Log log = LogFactory.getLog(HibernateDaoImpl.class);

	public void save(BasePO basePO) throws DataAccessException {
		getHibernateTemplate().save(basePO);
	}

	public int save(List<BasePO> listBasePO) throws DataAccessException {
		for (int i = 0; i < listBasePO.size(); i++) {
			BasePO basePO = (BasePO) listBasePO.get(i);
			getHibernateTemplate().save(basePO);
		}
		return listBasePO.size();
	}

	public void update(BasePO basePO) throws DataAccessException {
		getHibernateTemplate().update(basePO);
	}

	public void update(List<BasePO> listBasePO) throws DataAccessException {
		for (int i = 0; i < listBasePO.size(); i++) {
			BasePO basePO = (BasePO) listBasePO.get(i);
			getHibernateTemplate().update(basePO);
		}
	}

	public void update(BasePO basePO, StringBuffer sbWhere) throws DataAccessException {
		String strUpdSql = "update " + basePO.getStrTableName() + " set "
				+ basePO.getStrUpdValues() + " where " + sbWhere.toString();
		Query query = getSession().createQuery(strUpdSql);
		query.executeUpdate();
	}

	public void delete(BasePO basePO) throws DataAccessException {
		if (basePO.getStrKeyWhere().toString().equals("")) {
			return;
		}
		delete(basePO, basePO.getStrKeyWhere());
	}

	public void delete(List<BasePO> listBasePO) throws DataAccessException {
		for (int i = 0; i < listBasePO.size(); i++) {
			BasePO basePO = (BasePO) listBasePO.get(i);
			delete(basePO);
		}
	}

	public void delete(BasePO basePO, StringBuffer sbWhere) throws DataAccessException {
		String strUpdSql = "delete " + basePO.getStrTableName() + " "
				+ " where " + sbWhere.toString();
		Query query = getSession().createQuery(strUpdSql);
		query.executeUpdate();
	}

	public BasePO selectSingle(BasePO basePO) throws DataAccessException {
		List listResult = getHibernateTemplate().find(
				" from " + basePO.getStrTableName() + " as "
						+ basePO.getStrAliasName() + " where "
						+ basePO.getStrKeyWhere());
		if ((listResult == null) || (listResult.size() == 0))
			return null;
		return (BasePO) listResult.get(0);
	}

	public List select(BasePO basePO) throws DataAccessException {
		StringBuffer sbSql = new StringBuffer(" from " + basePO.getStrTableName() + " " + basePO.getStrAliasName());
		if ((basePO.getStrWhere() != null) && (!basePO.getStrWhere().toString().equals(""))) {
			sbSql.append(" where " + basePO.getStrWhere());
		}
		return getHibernateTemplate().find(sbSql.toString());
	}

	public List selectSplit(BasePO basePO, final int firstResult,final int maxResult) throws DataAccessException {
		StringBuffer sbSql = new StringBuffer(" from " + basePO.getStrTableName() + " " + basePO.getStrAliasName());
		Query query = getSession().createQuery(sbSql.toString());
		query.setFirstResult(firstResult);
		query.setMaxResults(maxResult);
		return query.list();
	}

	public List selectExact(BasePO basePO) throws DataAccessException {
		return selectExact(basePO, basePO.getStrExactWhere());
	}

	public List selectExact(BasePO basePO, StringBuffer sbWhere) throws DataAccessException {
		StringBuffer sbSql = new StringBuffer(" from ");
		sbSql.append(basePO.getStrTableName() + " ");
		sbSql.append(basePO.getStrAliasName());
		if ((sbWhere != null) && (!sbWhere.toString().equals(""))) {
			sbSql.append(" where " + sbWhere);
		}
		return getHibernateTemplate().find(sbSql.toString());
	}

	public void saveOrUpdate(BasePO basePO) {
		getHibernateTemplate().saveOrUpdate(basePO);
	}

	public void saveOrUpdate(List<BasePO> listBasePO) {
		for (int i = 0; i < listBasePO.size(); i++) {
			BasePO basePO = (BasePO) listBasePO.get(i);
			getHibernateTemplate().saveOrUpdate(basePO);
		}
	}

	public BasePO get(BasePO basePO, Serializable key) throws DataAccessException {
		return (BasePO) getHibernateTemplate().get(basePO.getClass(),
				"basePO.getStrKeyWhere()");
	}

	public List calculate(BasePO basePO, String strTemp, StringBuffer sbWhere)throws DataAccessException {
		StringBuffer sbSql = new StringBuffer("select " + strTemp + " from "
				+ basePO.getStrTableName() + " " + basePO.getStrAliasName());
		if ((sbWhere != null) && (!sbWhere.toString().equals(""))) {
			sbSql.append(" where " + sbWhere);
		}
		Query query = getSession().createQuery(sbSql.toString());
		return query.list();
	}

	public List calculate(BasePO basePO, String strTemp)throws DataAccessException {
		return calculate(basePO, strTemp, basePO.getStrExactWhere());
	}

	public void exeSql(StringBuffer sbSql) throws DataAccessException {
		Query query = getSession().createQuery(sbSql.toString());
		query.executeUpdate();
	}

	public HibernateDaoImpl getFromApplicationContext(ApplicationContext ctx) {
		return (HibernateDaoImpl) ctx.getBean("HibernateDaoImpl");
	}
	
	public List loadAll(final Class entityClass) throws DataAccessException {
		Criteria criteria = this.getSession().createCriteria(entityClass);
		return criteria.list();
	}

	public List loadAll(final Class entityClass, final int firstResult, final int maxResult) throws DataAccessException {
		Criteria criteria = getSession().createCriteria(entityClass).setFirstResult(firstResult).setMaxResults(maxResult);
		return criteria.list();
	}
	
	public List findByCriterions(Class clazz, List restrictions) throws DataAccessException {
		List objs = new ArrayList();
		Criteria criteria = getSession().createCriteria(clazz);
		Iterator it = restrictions.iterator();
		while (it.hasNext())
			criteria.add((Criterion) it.next());
		objs = criteria.list();
		return objs;
	}

	public List findByCriterions(Class clazz, List restrictions, int firstResult, int maxResult) throws DataAccessException {
		List objs = new ArrayList();
		Criteria criteria = getSession().createCriteria(clazz).setFirstResult(firstResult).setMaxResults(maxResult);
		Iterator it = restrictions.iterator();
		while (it.hasNext())
			criteria.add((Criterion) it.next());
		objs = criteria.list();
		return objs;
	}
}